package org.springblade.modules.auth.endpoint;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.apache.commons.lang.time.DateUtils;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.social.props.SocialProperties;
import org.springblade.core.social.utils.SocialUtil;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.modules.auth.provider.ITokenGranter;
import org.springblade.modules.auth.provider.TokenGranterBuilder;
import org.springblade.modules.auth.provider.TokenParameter;
import org.springblade.modules.auth.utils.WeChatLoginRequest;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.entity.UserInfo;
import org.springblade.modules.system.entity.UserOauth;
import org.springblade.modules.system.service.IUserOauthService;
import org.springblade.modules.system.service.IUserService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Key;
import java.util.*;

/**
 * 第三方登陆端点
 *
 * @author Chill
 */
@NonDS
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping(AppConstant.APPLICATION_AUTH_NAME+"szdx")
@ConditionalOnProperty(value = "social.enabled", havingValue = "true")
@Api(value = "第三方登陆", tags = "第三方登陆端点")
public class BladeSocialEndpointSZDX {

	private final IUserService userService;
	private final SocialProperties socialProperties;
	private final IUserOauthService userOauthService;
	private static final long EXPIRE_DATE=30*60*100000;

	//token秘钥
	private static final String TOKEN_SECRET = "ZCEQIUBFKSJBFJH2020BQWE";
	/**
	 * 授权完毕跳转
	 */
	@ApiOperation(value = "授权完毕跳转")
	@RequestMapping("/oauth/render/{source}")
	public void renderAuth(@PathVariable("source") String source, HttpServletResponse response) throws IOException {
		AuthRequest authRequest = SocialUtil.getAuthRequest(source, socialProperties);
		String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
		response.sendRedirect(authorizeUrl);
	}

	/**
	 * 获取认证信息
	 */
	@ApiOperation(value = "获取认证信息")
	@RequestMapping("/oauth/callback/{source}")
	public Object login(@PathVariable("source") String source, AuthCallback callback) {
		AuthRequest authRequest = SocialUtil.getAuthRequest(source, socialProperties);
		return authRequest.login(callback);
	}

	/**
	 * 撤销授权
	 */
	@ApiOperation(value = "撤销授权")
	@RequestMapping("/oauth/revoke/{source}/{token}")
	public Object revokeAuth(@PathVariable("source") String source, @PathVariable("token") String token) {
		AuthRequest authRequest = SocialUtil.getAuthRequest(source, socialProperties);
		return authRequest.revoke(AuthToken.builder().accessToken(token).build());
	}

	/**
	 * 续期accessToken
	 */
	@ApiOperation(value = "续期令牌")
	@RequestMapping("/oauth/refresh/{source}")
	public Object refreshAuth(@PathVariable("source") String source, String token) {
		AuthRequest authRequest = SocialUtil.getAuthRequest(source, socialProperties);
		return authRequest.refresh(AuthToken.builder().refreshToken(token).build());
	}
	public boolean jxToken(HttpServletRequest httpRequest){
		Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);

		//解析token
		Jws<Claims> claimsJws = Jwts.parserBuilder( ).setSigningKey(key).build( ).parseClaimsJws(httpRequest.getHeader("Authorization"));
		Claims body = claimsJws.getBody();
		String token= body.get("token").toString();
		AuthUtil.getHeader();
		QueryWrapper<UserOauth> wxyQueryWrapper = new QueryWrapper<>();
		wxyQueryWrapper.eq("uuid",token);
		List<UserOauth> wxies = userOauthService.list(wxyQueryWrapper);
		if (wxies.size()>0){
			return true;

		}else {
			return false;
		}
	}
	/**
	 * 微信小程序获取授权
	 */
	@PostMapping("/oauth/wechat")
	@ApiOperation(value = "第三方注册用户", notes = "传入user")
	public UserOauth login(@Validated @RequestBody WeChatLoginRequest request){

		String grantType = "wx_app";
		String userType = "app";
		TokenParameter tokenParameter = new TokenParameter();
		tokenParameter.getArgs().set("request", request).set("grantType", grantType).set("userType", userType);

		ITokenGranter granter = TokenGranterBuilder.getGranter(grantType);
		UserInfo userInfo = granter.grant(tokenParameter);
		System.out.println(userInfo.toString());

//		4、根据UserInfo创建Token
		UserOauth userOauth=new UserOauth();

		Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
		HashMap< String, Object > map = new HashMap<>( );
		map.put("token", userInfo.getUserOauth().getUuid());

		String token = Jwts.builder( ).setClaims(map).setExpiration(DateUtils.addDays(new Date( ), 1)).signWith(key).compact( ); //过期时间

		userOauth.setUuid(token);
		userOauth.setNickname(userInfo.getUserOauth().getNickname());
		userOauth.setGender(userInfo.getUserOauth().getGender());
		userOauth.setUserId(userInfo.getUserOauth().getUserId());
		userOauth.setAvatar(userInfo.getUserOauth().getAvatar());

		return userInfo.getUserOauth();
	}
	/**
	 * 微信小程序获取手机号后比对并且完成注册
	 */
	@ApiOperation(value = "用户注册")
	@GetMapping("/oauth/wechatRegister")
	public Object updateUserId(String account,String ouathId) {
		//新建空用户，将acount设为phone
		User user = new User();
		user.setAccount(account);
		user.setTenantId("000000");
		//查询该手机号对应的user
		User detail = userService.getOne(Condition.getQueryWrapper(user));
		//如果用户存在
		if (detail != null){
//			新建一个空第三方用户，将前端传来的id放进去
			UserOauth userOauth = new UserOauth();
			userOauth.setId(Long.valueOf(ouathId));
//			查询该第三方用户
			UserOauth one = userOauthService.getOne(Condition.getQueryWrapper(userOauth));
//			将该第三方用户的userId设为手机号对应的用户的userId
			one.setUserId(detail.getId());
//			更新该第三方用户
			userOauthService.updateById(one);
			return R.status(true);
		}
		return R.status(false);
	}


}

